﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using Common;
using Dao;
using Domain.Common;
using Domain.Map;
using Domain.Officers;
using Microsoft.Xna.Framework;

namespace Domain
{
    public partial class Building
    {
        /// <summary>
        /// 城池武将内政工作分派，使用优先比例法（根据城池战略，优先分配某种工作，且各个工作按一定比例分配）
        /// </summary>
        public void DispatchInternalTask()
        {
            //内政工作人员分派比例
            float endurancesp,
                recruitSoldiersp,
                agriculturesp,
                commercesp,
                technologysp,
                culturesp,
                publicSecuritysp,
                popularFeelingsp;
            //可分配数量
            int recruitSoldiersAvilableCount,
                endurancesAvilableCount,
                publicSecuritysAvilableCount,
                popularFeelingsAvilableCount,
                 commercesAvilableCount,
                  technologysAvilableCount,
                   culturesAvilableCount,
                agriculturesAvilableCount;
            OwnedOfficers.ForEach(x => x.WorkType = null);//设置所有武将暂时不工作

            if (this.StrategyType == StrategyType.War)
            {
                #region 战争策略的城池工作分配
                //设置策略工作的分工比例
                recruitSoldiersp = 0.4f;
                endurancesp = 0.3f;
                publicSecuritysp = 0.1f;
                popularFeelingsp = 0.1f;
                agriculturesp = 0.1f;
                int count = OwnedOfficers.Count();
                //计算各个重要工作的分配武将数额
                recruitSoldiersAvilableCount = (int)(count * recruitSoldiersp);
                endurancesAvilableCount = (int)(count * endurancesp);
                publicSecuritysAvilableCount = (int)(count * publicSecuritysp);
                popularFeelingsAvilableCount = (int)(count * popularFeelingsp);
                agriculturesAvilableCount = (int)(count * agriculturesp);
                //根据城池内政现状，修正实际分配人数
                recruitSoldiersAvilableCount = RecruitSoldierCountAmend(recruitSoldiersAvilableCount);
                endurancesAvilableCount = EnduranceCountAmend(endurancesAvilableCount);
                publicSecuritysAvilableCount = PublicSecurityCountAmend(publicSecuritysAvilableCount);
                popularFeelingsAvilableCount = PopularFeelingCountAmend(popularFeelingsAvilableCount);
                agriculturesAvilableCount = AgricultureCountAmend(agriculturesAvilableCount);
                //根据战略优先级分配工作人员,先后顺序分配
                RecruitSoldiersWorkDispatch(recruitSoldiersAvilableCount);
                EndurancesWorkDispatch(endurancesAvilableCount);
                PublicSecuritysWorkDispatch(publicSecuritysAvilableCount);
                PopularFeelingsWorkDispatch(popularFeelingsAvilableCount);
                AgriculturesWorkDispatch(agriculturesAvilableCount);
                RemainOfficerDispatch();

                #endregion
            }
            else if (this.StrategyType == StrategyType.Defense)
            {
                #region 防御策略的城池工作分配
                //设置策略工作的分工比例
                recruitSoldiersp = 0.3f;
                endurancesp = 0.3f;
                agriculturesp = 0.2f;
                publicSecuritysp = 0.1f;
                popularFeelingsp = 0.1f;

                int count = OwnedOfficers.Count();
                //计算各个重要工作的分配武将数额
                recruitSoldiersAvilableCount = (int)(count * recruitSoldiersp);
                endurancesAvilableCount = (int)(count * endurancesp);
                agriculturesAvilableCount = (int)(count * agriculturesp);
                publicSecuritysAvilableCount = (int)(count * publicSecuritysp);
                popularFeelingsAvilableCount = (int)(count * popularFeelingsp);

                //根据城池内政现状，修正实际分配人数
                recruitSoldiersAvilableCount = RecruitSoldierCountAmend(recruitSoldiersAvilableCount);
                endurancesAvilableCount = EnduranceCountAmend(endurancesAvilableCount);
                agriculturesAvilableCount = AgricultureCountAmend(agriculturesAvilableCount);
                publicSecuritysAvilableCount = PublicSecurityCountAmend(publicSecuritysAvilableCount);
                popularFeelingsAvilableCount = PopularFeelingCountAmend(popularFeelingsAvilableCount);

                //根据战略优先级分配工作人员,先后顺序分配
                RecruitSoldiersWorkDispatch(recruitSoldiersAvilableCount);
                EndurancesWorkDispatch(endurancesAvilableCount);
                AgriculturesWorkDispatch(agriculturesAvilableCount);
                PublicSecuritysWorkDispatch(publicSecuritysAvilableCount);
                PopularFeelingsWorkDispatch(popularFeelingsAvilableCount);
                RemainOfficerDispatch();

                #endregion
            }
            else if (this.StrategyType == StrategyType.Internal)
            {
                #region 注重内政策略的城池工作分配
                DealBuildingExtend();//优先考虑分配
                //设置策略工作的分工比例
                agriculturesp = 0.4f;
                commercesp = 0.2f;
                technologysp = 0.2f;
                publicSecuritysp = 0.1f;
                popularFeelingsp = 0.1f;

                int count = OwnedOfficers.Count(x => x.WorkType == null);//去除优先分配扩建、登庸等职务后可用人数
                //计算各个重要工作的分配武将数额
                agriculturesAvilableCount = (int)(count * agriculturesp);
                commercesAvilableCount = (int)(count * commercesp);
                technologysAvilableCount = (int)(count * technologysp);
                publicSecuritysAvilableCount = (int)(count * publicSecuritysp);
                popularFeelingsAvilableCount = (int)(count * popularFeelingsp);

                //根据城池内政现状，修正实际分配人数
                agriculturesAvilableCount = AgricultureCountAmend(agriculturesAvilableCount);
                commercesAvilableCount = CommerceCountAmend(commercesAvilableCount);
                technologysAvilableCount = TechnologyCountAmend(technologysAvilableCount);
                publicSecuritysAvilableCount = PublicSecurityCountAmend(publicSecuritysAvilableCount);
                popularFeelingsAvilableCount = PopularFeelingCountAmend(popularFeelingsAvilableCount);

                //根据战略优先级分配工作人员,先后顺序分配
                AgriculturesWorkDispatch(agriculturesAvilableCount);
                CommercesWorkDispatch(commercesAvilableCount);
                TechnologyWorkDispatch(technologysAvilableCount);
                PublicSecuritysWorkDispatch(publicSecuritysAvilableCount);
                PopularFeelingsWorkDispatch(popularFeelingsAvilableCount);
                RemainOfficerDispatch();

                #endregion
            }
            else if (this.StrategyType == StrategyType.Send)
            {
                #region 注重输送策略的城池工作分配
                DealBuildingExtend();//优先考虑分配
                //设置策略工作的分工比例 
                recruitSoldiersp = 0.3f;
                agriculturesp = 0.3f;
                commercesp = 0.3f;
                popularFeelingsp = 0.1f;
                int count = OwnedOfficers.Count(x => x.WorkType == null);//去除优先分配扩建、登庸等职务后可用人数
                //计算各个重要工作的分配武将数额
                recruitSoldiersAvilableCount = (int)(count * recruitSoldiersp);
                agriculturesAvilableCount = (int)(count * agriculturesp);
                commercesAvilableCount = (int)(count * commercesp);
                popularFeelingsAvilableCount = (int)(count * popularFeelingsp);

                //根据城池内政现状，修正实际分配人数
                recruitSoldiersAvilableCount = RecruitSoldierCountAmend(recruitSoldiersAvilableCount);
                agriculturesAvilableCount = AgricultureCountAmend(agriculturesAvilableCount);
                commercesAvilableCount = CommerceCountAmend(commercesAvilableCount);
                popularFeelingsAvilableCount = PopularFeelingCountAmend(popularFeelingsAvilableCount);
                //根据战略优先级分配工作人员,先后顺序分配
                RecruitSoldiersWorkDispatch(recruitSoldiersAvilableCount);
                AgriculturesWorkDispatch(agriculturesAvilableCount);
                CommercesWorkDispatch(commercesAvilableCount);
                PopularFeelingsWorkDispatch(popularFeelingsAvilableCount);
                RemainOfficerDispatch();

                #endregion
            }
            else if (this.StrategyType == StrategyType.Normal)
            {
                #region 均衡发展策略的城池工作分配
                DealBuildingExtend();//优先考虑分配
                //设置策略工作的分工比例
                agriculturesp = 0.2f;
                recruitSoldiersp = 0.2f;
                endurancesp = 0.1f;
                commercesp = 0.1f;
                technologysp = 0.1f;
                culturesp = 0.1f;
                publicSecuritysp = 0.1f;
                popularFeelingsp = 0.1f;

                int count = OwnedOfficers.Count(x => x.WorkType == null);//去除优先分配扩建、登庸等职务后可用人数
                //计算各个重要工作的分配武将数额
                agriculturesAvilableCount = (int)(count * agriculturesp);
                commercesAvilableCount = (int)(count * commercesp);
                endurancesAvilableCount = (int)(count * endurancesp);
                technologysAvilableCount = (int)(count * technologysp);
                culturesAvilableCount = (int)(count * culturesp);
                publicSecuritysAvilableCount = (int)(count * publicSecuritysp);
                popularFeelingsAvilableCount = (int)(count * popularFeelingsp);
                recruitSoldiersAvilableCount = (int)(count * recruitSoldiersp);
                //根据城池内政现状，修正实际分配人数
                agriculturesAvilableCount = AgricultureCountAmend(agriculturesAvilableCount);
                commercesAvilableCount = CommerceCountAmend(commercesAvilableCount);
                endurancesAvilableCount = EnduranceCountAmend(endurancesAvilableCount);
                technologysAvilableCount = TechnologyCountAmend(technologysAvilableCount);
                culturesAvilableCount = CultureCountAmend(culturesAvilableCount);
                publicSecuritysAvilableCount = PublicSecurityCountAmend(publicSecuritysAvilableCount);
                popularFeelingsAvilableCount = PopularFeelingCountAmend(popularFeelingsAvilableCount);
                recruitSoldiersAvilableCount = RecruitSoldierCountAmend(recruitSoldiersAvilableCount);
                //根据战略优先级分配工作人员,先后顺序分配
                RecruitSoldiersWorkDispatch(recruitSoldiersAvilableCount);
                AgriculturesWorkDispatch(agriculturesAvilableCount);
                EndurancesWorkDispatch(endurancesAvilableCount);
                CommercesWorkDispatch(commercesAvilableCount);
                TechnologyWorkDispatch(technologysAvilableCount);
                CultureWorkDispatch(culturesAvilableCount);
                PublicSecuritysWorkDispatch(publicSecuritysAvilableCount);
                PopularFeelingsWorkDispatch(popularFeelingsAvilableCount);
                RemainOfficerDispatch();

                #endregion
            }
            #region 日志打印
            if(CurrentBuildingLevel!=null)
            Logger.Info(string.Format("城池农业:{0} 商业:{1} 耐久:{2} 技术:{3} 文化:{4} 民心:{5} 治安:{6} 兵役:{7} 人口:{8}"
                , Agriculture + "/" + CurrentBuildingLevel.AgricultureMax, Commerce + "/" + CurrentBuildingLevel.CommerceMax,
                Endurance + "/" + CurrentBuildingLevel.EnduranceMax, Technology + "/" + CurrentBuildingLevel.TechnologyMax,
                Culture + "/" + CurrentBuildingLevel.CultureMax, PopularFeelings + "/100",
                PublicSecurity + "/100", SoldierPopulation, Population + "/" + CurrentBuildingLevel.PopulationMax));
            foreach (var officer in OwnedOfficers)
            {
                if (officer.WorkType != null)
                    Logger.Info(string.Format("武将:{0} 分配任务为:{1}", officer.FirstName + officer.Name, EnumUtil.Getdescription(officer.WorkType)));
                else
                    Logger.Info(string.Format("武将:{0} 无任务", officer.FirstName + officer.Name));
            }
            #endregion
        }
        /// <summary>
        /// 处理城池是否需要扩建
        /// </summary>
        private void DealBuildingExtend()
        {
            //人口达到城市最大人口容量80%时，需要扩建城池
            if (this.CurrentBuildingLevel != null && this.IsExtendingBuilding == false &&
                (this.Population / this.CurrentBuildingLevel.PopulationMax) >= 0.8)
            {
                this.IsExtendingBuilding = true;
            }
            if (this.IsExtendingBuilding)
                ExtendBuildingWorkDispatch(1); //扩建城墙只需一个武将负责即可
        }
        /// <summary>
        /// 技术人数修正
        /// </summary>
        /// <returns></returns>
        public int TechnologyCountAmend(int sourcesCount)
        {
            if (this.CurrentBuildingLevel == null)
                return 0;
            int count = 0;
            int v = this.CurrentBuildingLevel.TechnologyMax - this.Technology;
            if (v < 100)
                count = 1;
            else if (v < 200 && v >= 100)
                count = sourcesCount > 2 ? 2 : sourcesCount;
            else if (v < 300 && v >= 200)
                count = sourcesCount > 3 ? 3 : sourcesCount;
            else if (v < 400 && v >= 300)
                count = sourcesCount > 4 ? 4 : sourcesCount;
            else
                count = sourcesCount;
            return count;
        }
        /// <summary>
        /// 商业人数修正
        /// </summary>
        /// <returns></returns>
        public int CommerceCountAmend(int sourcesCount)
        {
            if (this.CurrentBuildingLevel == null)
                return 0;
            int count = 0;
            int v = this.CurrentBuildingLevel.CommerceMax - this.Commerce;
            if (v < 100)
                count = 1;
            else if (v < 200 && v >= 100)
                count = sourcesCount > 2 ? 2 : sourcesCount;
            else if (v < 300 && v >= 200)
                count = sourcesCount > 3 ? 3 : sourcesCount;
            else if (v < 400 && v >= 300)
                count = sourcesCount > 4 ? 4 : sourcesCount;
            else
                count = sourcesCount;
            return count;
        }
        /// <summary>
        /// 农业人数修正
        /// </summary>
        /// <returns></returns>
        public int AgricultureCountAmend(int sourcesCount)
        {
            if (this.CurrentBuildingLevel == null)
                return 0;
            int count = 0;
            int v = this.CurrentBuildingLevel.AgricultureMax - this.Agriculture;
            if (v < 100)
                count = 1;
            else if (v < 200 && v >= 100)
                count = sourcesCount > 2 ? 2 : sourcesCount;
            else if (v < 300 && v >= 200)
                count = sourcesCount > 3 ? 3 : sourcesCount;
            else if (v < 400 && v >= 300)
                count = sourcesCount > 4 ? 4 : sourcesCount;
            else
                count = sourcesCount;
            return count;
        } /// <summary>
        /// 文化人数修正
        /// </summary>
        /// <returns></returns>
        public int CultureCountAmend(int sourcesCount)
        {
            if (this.CurrentBuildingLevel == null)
                return 0;
            int count = 0;
            int v = this.CurrentBuildingLevel.CultureMax - this.Culture;
            if (v < 100)
                count = 1;
            else if (v < 200 && v >= 100)
                count = sourcesCount > 2 ? 2 : sourcesCount;
            else if (v < 300 && v >= 200)
                count = sourcesCount > 3 ? 3 : sourcesCount;
            else if (v < 400 && v >= 300)
                count = sourcesCount > 4 ? 4 : sourcesCount;
            else
                count = sourcesCount;
            return count;
        }
        /// <summary>
        /// 耐久人数修正
        /// </summary>
        /// <returns></returns>
        public int EnduranceCountAmend(int sourcesCount)
        {
            int count = 0;
            int v = 0;
            if (this.CurrentBuildingLevel != null)
                v = this.CurrentBuildingLevel.EnduranceMax - this.Endurance;
            else
                v = this._fixEnduranceMax - this.Endurance;
            if (v < 100)
                count = 1;
            else if (v < 200 && v >= 100)
                count = sourcesCount > 2 ? 2 : sourcesCount;
            else if (v < 300 && v >= 200)
                count = sourcesCount > 3 ? 3 : sourcesCount;
            else if (v < 400 && v >= 300)
                count = sourcesCount > 4 ? 4 : sourcesCount;
            else
                count = sourcesCount;
            return count;
        }
        /// <summary>
        /// 扩建人数修正
        /// </summary>
        /// <returns></returns>
        public int ExtendBuildingCountAmend(int sourcesCount)
        {
            if (this.CurrentBuildingLevel == null)
                return 0;
            int count = 0;
            BuildingLevel nextLevel = BuildingLevel.BuildingLevels[(short)(CurrentBuildingLevel.Id + 1)];
            int v = nextLevel.EnduranceMax - this.CurrentExtendBuilding;
            if (v < 100)
                count = 1;
            else if (v < 200 && v >= 100)
                count = sourcesCount > 2 ? 2 : sourcesCount;
            else if (v < 300 && v >= 200)
                count = sourcesCount > 3 ? 3 : sourcesCount;
            else if (v < 400 && v >= 300)
                count = sourcesCount > 4 ? 4 : sourcesCount;
            else
                count = sourcesCount;
            return count;
        }
        /// <summary>
        /// 募兵人数修正
        /// </summary>
        /// <returns></returns>
        public int RecruitSoldierCountAmend(int sourcesCount)
        {
            int count = 0;
            if (this.SoldierPopulation < 500 && this.SoldierPopulation > 100)
                count = 1;
            else if (this.SoldierPopulation < 1000 && this.SoldierPopulation >= 500)
                count = sourcesCount > 2 ? 2 : sourcesCount;
            else if (this.SoldierPopulation < 1500 && this.SoldierPopulation >= 1000)
                count = sourcesCount > 3 ? 3 : sourcesCount;
            else if (this.SoldierPopulation < 2000 && this.SoldierPopulation >= 1500)
                count = sourcesCount > 4 ? 4 : sourcesCount;
            else
                count = sourcesCount;
            return count;
        }
        /// <summary>
        /// 治安人数修正
        /// </summary>
        /// <returns></returns>
        public int PublicSecurityCountAmend(int sourcesCount)
        {
            int count = 0;
            if (this.PublicSecurity < 100 && this.PublicSecurity >= 90)
                count = 1;
            else if (this.PublicSecurity < 90 && this.PublicSecurity >= 80)
                count = sourcesCount > 2 ? 2 : sourcesCount;
            else if (this.PublicSecurity < 80 && this.PublicSecurity >= 70)
                count = sourcesCount > 3 ? 3 : sourcesCount;
            else if (this.PublicSecurity < 70 && this.PublicSecurity >= 60)
                count = sourcesCount > 4 ? 4 : sourcesCount;
            else
                count = sourcesCount;
            return count;
        }

        /// <summary>
        ///  民心人数修正
        /// </summary>
        /// <returns></returns>
        public int PopularFeelingCountAmend(int sourcesCount)
        {
            int count = 0;
            if (this.PopularFeelings < 100 && this.PopularFeelings >= 90)
                count = 1;
            else if (this.PopularFeelings < 90 && this.PopularFeelings >= 80)
                count = sourcesCount > 2 ? 2 : sourcesCount;
            else if (this.PopularFeelings < 80 && this.PopularFeelings >= 70)
                count = sourcesCount > 3 ? 3 : sourcesCount;
            else if (this.PopularFeelings < 70 && this.PopularFeelings >= 60)
                count = sourcesCount > 4 ? 4 : sourcesCount;
            else
                count = sourcesCount;
            return count;
        }

        /// <summary>
        /// 剩余武将工作分配,采用非重点任务的随机安排
        /// 如果某项内政已满值，则递归分配
        /// </summary>
        /// <param name="recursionTimes">递归次数，防止堆栈溢出。</param>
        public void RemainOfficerDispatch(int recursionTimes = 30)
        {
            if (recursionTimes == 0)//递归次数用尽，则跳出递归
                return;
            if (!OwnedOfficers.Any(x => x.WorkType == null))//如果没有未分配工作的
                return;
            string work = "";

            switch (this.StrategyType)
            {

                case StrategyType.War:
                    string[] arry0 = new string[] { "culture", "technology", "commerce" };
                    int v0 = rd.Next(0, 2);
                    work = arry0[v0];
                    break;
                case StrategyType.Defense:
                    string[] arry1 = new string[] { "culture", "technology", "commerce" };
                    int v1 = rd.Next(0, 2);
                    work = arry1[v1];
                    break;
                case StrategyType.Internal:
                    string[] arry2 = new string[] { "endurance", "recruitSoldier", "culture" };
                    int v2 = rd.Next(0, 2);
                    work = arry2[v2];
                    break;
                case StrategyType.Send:
                    string[] arry3 = new string[] { "technology", "culture", "publicSecurity", "endurance" };
                    int v3 = rd.Next(0, 3);
                    work = arry3[v3];
                    break;
                case StrategyType.Normal://防止有个别武将分配不到任务
                    string[] arry4 = new string[] { "technology", "culture", "commerce", "endurance" };
                    int v4 = rd.Next(0, 3);
                    work = arry4[v4];
                    break;
            }
            switch (work)
            {
                case "culture":
                    CultureWorkDispatch(1); break;
                case "technology":
                    TechnologyWorkDispatch(1); break;
                case "commerce":
                    CommercesWorkDispatch(1); break;
                case "publicSecurity":
                    PublicSecuritysWorkDispatch(1); break;
                case "endurance":
                    EndurancesWorkDispatch(1); break;
                case "recruitSoldier":
                    RecruitSoldiersWorkDispatch(1); break;
            }
            RemainOfficerDispatch(--recursionTimes);
        }
        /// <summary>
        /// 文化工作分配
        /// </summary>
        public void CultureWorkDispatch(int count)
        {
            if (this.CurrentBuildingLevel == null || Culture == CurrentBuildingLevel.CultureMax)
                return;
            for (int i = 0; i < count; i++)
            {
                //特长优先分配
                var ret0 = OwnedOfficers.Where(x => x.WorkType == null && (x.Abilities.Contains(OfficerAbility.Reputation) || x.Abilities.Contains(OfficerAbility.Doctor))).ToList();
                if (ret0.Any())
                {
                    var temp0 = ret0.First();
                    temp0.WorkType = WorkType.Endurance;
                    continue;
                }
                var ret1 = OwnedOfficers.Where(x => x.WorkType == null).OrderByDescending(x => x.Intelligence).ThenByDescending(x => x.Politics);
                if (ret1.Any())
                {
                    var temp1 = ret1.First();
                    temp1.WorkType = WorkType.Culture;
                }

            }
        }
        /// <summary>
        /// 商业工作分配
        /// </summary>
        public void CommercesWorkDispatch(int count)
        {
            if (this.CurrentBuildingLevel == null || Commerce == CurrentBuildingLevel.CommerceMax)
                return;
            for (int i = 0; i < count; i++)
            {
                //特长优先分配
                var ret0 = OwnedOfficers.Where(x => x.WorkType == null && x.Abilities.Contains(OfficerAbility.Business)).ToList();
                if (ret0.Any())
                {
                    var temp0 = ret0.First();
                    temp0.WorkType = WorkType.Endurance;
                    continue;
                }
                var ret1 = OwnedOfficers.Where(x => x.WorkType == null).OrderByDescending(x => x.Politics);
                if (ret1.Any())
                {
                    var temp1 = ret1.First();
                    temp1.WorkType = WorkType.Commerce;
                }

            }
        }

        /// <summary>
        /// 农业工作分配
        /// </summary>
        public void AgriculturesWorkDispatch(int count)
        {
            if (this.CurrentBuildingLevel == null || Agriculture == CurrentBuildingLevel.AgricultureMax)
                return;
            for (int i = 0; i < count; i++)
            {
                //特长优先分配
                var ret0 = OwnedOfficers.Where(x => x.WorkType == null && (x.Abilities.Contains(OfficerAbility.Reclaim) || x.Abilities.Contains(OfficerAbility.WaterProject))).ToList();
                if (ret0.Any())
                {
                    var temp0 = ret0.First();
                    temp0.WorkType = WorkType.Agriculture;
                    continue;
                }
                var ret1 = OwnedOfficers.Where(x => x.WorkType == null).OrderByDescending(x => x.Politics);
                if (ret1.Any())
                {
                    var temp1 = ret1.First();
                    temp1.WorkType = WorkType.Agriculture;
                }

            }
        }
        /// <summary>
        /// 技术工作分配
        /// </summary>
        public void TechnologyWorkDispatch(int count)
        {
            if (this.CurrentBuildingLevel == null||Technology == CurrentBuildingLevel.TechnologyMax)
                return;
            for (int i = 0; i < count; i++)
            {
                //特长优先分配
                var ret0 = OwnedOfficers.Where(x => x.WorkType == null && x.Abilities.Contains(OfficerAbility.Armament)).ToList();
                if (ret0.Any())
                {
                    var temp0 = ret0.First();
                    temp0.WorkType = WorkType.Endurance;
                    continue;
                }
                var ret1 = OwnedOfficers.Where(x => x.WorkType == null).OrderByDescending(x => x.Intelligence);
                if (ret1.Any())
                {
                    var temp1 = ret1.First();
                    temp1.WorkType = WorkType.Technology;
                }

            }
        }
        /// <summary>
        /// 民心工作分配
        /// </summary>
        public void PopularFeelingsWorkDispatch(int count)
        {
            if (PopularFeelings == 100)
                return;
            for (int i = 0; i < count; i++)
            {
                //特长优先分配
                var ret0 = OwnedOfficers.Where(x => x.WorkType == null && (x.Abilities.Contains(OfficerAbility.Reputation) || x.Abilities.Contains(OfficerAbility.Eloquence))).ToList();
                if (ret0.Any())
                {
                    var temp0 = ret0.First();
                    temp0.WorkType = WorkType.PopularFeelings;
                    continue;
                }
                var ret1 = OwnedOfficers.Where(x => x.WorkType == null).OrderByDescending(x => x.Reputation).ThenByDescending(x => x.Glamour);
                if (ret1.Any())
                {
                    var temp1 = ret1.First();
                    temp1.WorkType = WorkType.PopularFeelings;
                }

            }
        }

        /// <summary>
        /// 治安工作分配
        /// </summary>
        public void PublicSecuritysWorkDispatch(int count)
        {
            if (PublicSecurity == 100)
                return;
            for (int i = 0; i < count; i++)
            {
                //特长优先分配
                var ret0 = OwnedOfficers.Where(x => x.WorkType == null && x.Abilities.Contains(OfficerAbility.CruelOfficials)).ToList();
                if (ret0.Any())
                {
                    var temp0 = ret0.First();
                    temp0.WorkType = WorkType.PublicSecurity;
                    continue;
                }
                var ret1 = OwnedOfficers.Where(x => x.WorkType == null).OrderByDescending(x => x.Commander).ThenByDescending(x => x.Strength);
                if (ret1.Any())
                {
                    var temp1 = ret1.First();
                    temp1.WorkType = WorkType.PublicSecurity;
                }

            }
        }

        /// <summary>
        /// 耐久工作分配
        /// </summary>
        public void EndurancesWorkDispatch(int count)
        {
            if (CurrentBuildingLevel!=null&&Endurance == CurrentBuildingLevel.EnduranceMax)
                return;
            for (int i = 0; i < count; i++)
            {
                //特长优先分配
                var ret0 = OwnedOfficers.Where(x => x.WorkType == null && (x.Abilities.Contains(OfficerAbility.Build) || x.Abilities.Contains(OfficerAbility.Eloquence))).ToList();
                if (ret0.Any())
                {
                    var temp0 = ret0.First();
                    temp0.WorkType = WorkType.Endurance;
                    continue;
                }
                var ret1 = OwnedOfficers.Where(x => x.WorkType == null).OrderByDescending(x => x.Commander).ThenByDescending(x => x.Politics);
                if (ret1.Any())
                {
                    var temp1 = ret1.First();
                    temp1.WorkType = WorkType.Endurance;
                }

            }
        }
        /// <summary>
        /// 扩建工作分配
        /// </summary>
        public void ExtendBuildingWorkDispatch(int count)
        {
            if (!this.IsExtendingBuilding||this.CurrentBuildingLevel==null)
                return;
            for (int i = 0; i < count; i++)
            {
                //特长优先分配
                var ret0 = OwnedOfficers.Where(x => x.WorkType == null && (x.Abilities.Contains(OfficerAbility.Build) || x.Abilities.Contains(OfficerAbility.Eloquence))).ToList();
                if (ret0.Any())
                {
                    var temp0 = ret0.First();
                    temp0.WorkType = WorkType.ExtendBuilding;
                    continue;
                }
                var ret1 = OwnedOfficers.Where(x => x.WorkType == null).OrderByDescending(x => x.Commander).ThenByDescending(x => x.Politics);
                if (ret1.Any())
                {
                    var temp1 = ret1.First();
                    temp1.WorkType = WorkType.ExtendBuilding;
                }

            }
        }

        /// <summary>
        /// 募兵工作分配
        /// </summary>
        public void RecruitSoldiersWorkDispatch(int count)
        {
            if (SoldierPopulation == 0)
                return;
            for (int i = 0; i < count; i++)
            {
                //特长优先分配
                var ret0 = OwnedOfficers.Where(x => x.WorkType == null && x.Abilities.Contains(OfficerAbility.Reputation)).ToList();
                if (ret0.Any())
                {
                    var temp0 = ret0.First();
                    temp0.WorkType = WorkType.RecruitSoldier;
                    continue;
                }
                var ret1 = OwnedOfficers.Where(x => x.WorkType == null).OrderByDescending(x => x.Reputation).ThenByDescending(x => x.Glamour).ThenByDescending(x => x.Commander).ThenByDescending(x => x.Politics);
                if (ret1.Any())
                {
                    var temp1 = ret1.First();
                    temp1.WorkType = WorkType.RecruitSoldier;
                }
            }
        }
        /// <summary>
        /// 农业发展增值
        /// </summary>
        /// <param name="days">天数</param>
        /// <param name="fund">资金</param>
        /// <returns></returns>
        public void DevelopAgriculture(int days, int fund)
        {
            if (this.CurrentBuildingLevel == null)
                return;
            double ret0 = Population * 0.000001;//人口加成，十万分之一
            double ret1 = Technology * 0.001;//技术加成
            double ret3 = PublicSecurity * 0.01;//治安加成
            double ret4 = PopularFeelings * 0.01;//民心加成
            double ret5 = fund * 0.01;//资金加成
            double ret6 = 0;//武将政治加成
            foreach (var officer in this.OwnedOfficers.Where(x => x.WorkType == WorkType.Agriculture).ToList())
            {
                ret6 += officer.Politics * 0.01;
                officer.UpdateDevelopAgriculturePerformance(days);
            }
            double total = ret0 + ret1 + ret3 + ret4 + ret5 + ret6;
            int ret = (int)(total * days);//天数加成，取整
            this.Agriculture += ret;
            if (this.Agriculture > CurrentBuildingLevel.AgricultureMax)
                this.Agriculture = CurrentBuildingLevel.AgricultureMax;
            Logger.Info("农业加成:" + ret);
            Logger.Debug("农业加成:" + ret + ",参数:days=" + days + "&fund=" + fund);
        }
        /// <summary>
        /// 商业发展增值
        /// </summary>
        /// <param name="days">天数</param>
        /// <param name="fund">资金</param>
        /// <returns></returns>
        public void DevelopCommerce(int days, int fund)
        {
            if (this.CurrentBuildingLevel == null)
                return;
            double ret0 = Population * 0.000001;//人口加成，十万分之一
            double ret3 = PublicSecurity * 0.01;//治安加成
            double ret4 = PopularFeelings * 0.01;//民心加成
            double ret5 = fund * 0.01;//资金加成
            double ret6 = 0;//武将政治加成
            foreach (var officer in this.OwnedOfficers.Where(x => x.WorkType == WorkType.Commerce).ToList())
            {
                ret6 += officer.Politics * 0.01;
                officer.UpdateDevelopCommercePerformance(days);
            }
            double total = ret0 + ret3 + ret4 + ret5 + ret6;
            int ret = (int)(total * days);//天数加成，取整
            this.Commerce += ret;
            if (this.Commerce > CurrentBuildingLevel.CommerceMax)
                this.Commerce = CurrentBuildingLevel.CommerceMax;
            Logger.Info("商业加成:" + ret);
        }
        /// <summary>
        /// 技术发展增值
        /// </summary>
        /// <param name="days">天数</param>
        /// <param name="fund">资金</param>
        /// <returns></returns>
        public void DevelopTechnology(int days, int fund)
        {
            if (this.CurrentBuildingLevel == null)
                return;
            double ret5 = fund * 0.01;//资金加成
            double ret6 = 0;//武将政治加成
            foreach (var officer in this.OwnedOfficers.Where(x => x.WorkType == WorkType.Technology).ToList())
            {
                ret6 += officer.Intelligence * 0.1;
                officer.UpdateDevelopTechnologyPerformance(days);
            }
            double total = ret5 + ret6;
            int ret = (int)(total * days);//天数加成，取整
            this.Technology += ret;
            if (this.Technology > CurrentBuildingLevel.TechnologyMax)
                this.Technology = CurrentBuildingLevel.TechnologyMax;
            Logger.Info("技术加成:" + ret);
        }
        /// <summary>
        /// 文化发展增值
        /// </summary>
        /// <param name="days">天数</param>
        /// <param name="fund">资金</param>
        /// <returns></returns>
        public void DevelopCulture(int days, int fund)
        {
            if (this.CurrentBuildingLevel == null)
                return;
            double ret0 = Population * 0.000001;//人口加成，十万分之一
            double ret5 = fund * 0.01;//资金加成
            double ret6 = 0;//武将政治加成
            double ret7 = 0;//武将智力加成
            foreach (var officer in this.OwnedOfficers.Where(x => x.WorkType == WorkType.Culture).ToList())
            {
                ret6 += officer.Politics * 0.05;
                ret6 += officer.Intelligence * 0.05;
                officer.UpdateDevelopCulturePerformance(days);
            }
            double total = ret0 + ret5 + ret6 + ret7;
            int ret = (int)(total * days);//天数加成，取整
            this.Culture += ret;
            if (this.Culture > CurrentBuildingLevel.CultureMax)
                this.Culture = CurrentBuildingLevel.CultureMax;
            Logger.Info("文化加成:" + ret);
        }
        /// <summary>
        /// 治安发展增值
        /// </summary>
        /// <param name="days">天数</param>
        /// <param name="fund">资金</param>
        /// <returns></returns>
        public void DevelopPublicSecurity(int days, int fund)
        {
            double ret5 = fund * 0.01;//资金加成
            double ret6 = 0;//武将武力加成
            double ret7 = 0;//武将统率加成
            foreach (var officer in this.OwnedOfficers.Where(x => x.WorkType == WorkType.PublicSecurity).ToList())
            {
                ret6 += officer.Strength * 0.001;
                ret7 += officer.Commander * 0.005;
                officer.UpdateDevelopPublicSecurityPerformance(days);
            }
            double total = ret5 + ret6 + ret7;
            int ret = (int)(total * days);//天数加成，取整
            this.PublicSecurity += ret;
            if (this.PublicSecurity > 100)
                this.PublicSecurity = 100;
            Logger.Info("治安加成:" + ret);
        }
        /// <summary>
        /// 民心发展增值
        /// </summary>
        /// <param name="days">天数</param>
        /// <param name="fund">资金</param>
        /// <returns></returns>
        public void DevelopPopularFeelings(int days, int fund)
        {
            double ret1=0, ret2=0, ret3=0;
            if (this.CurrentBuildingLevel != null)
            {
                 ret1 = Agriculture / Population >= 0.2 ? Agriculture / Population * 1 : 0;//农业加成,农业相对人口更发达，则民心稳
                 ret2 = Commerce / Population >= 0.2 ? Commerce / Population * 0.1 : 0;//商业加成，商业相对人口更发达，则民心稳
                 ret3 = Culture / Population >= 0.2 ? Culture / Population * 0.1 : 0;//文化加成，文化教育相对人口更发达，则民心稳
            }
            double ret4 = PublicSecurity * 0.001;//治安加成
            double ret5 = fund * 0.01;//资金加成
            double ret6 = 0;//武将魅力加成
            double ret7 = 0;//武将名望加成
            foreach (var officer in this.OwnedOfficers.Where(x => x.WorkType == WorkType.PopularFeelings).ToList())
            {
                ret6 += officer.Glamour * 0.001;
                ret7 += officer.Reputation * 0.0001;
                officer.UpdateDevelopPopularFeelingsPerformance(days);
            }
            double total = ret1 + ret2 + ret3 + ret4 + ret5 + ret6 + ret7;
            int ret = (int)(total * days);//天数加成，取整
            this.PopularFeelings += ret;
            if (this.PopularFeelings > 100)
                this.PopularFeelings = 100;
            Logger.Info("民心加成:" + ret);
        }
        /// <summary>
        /// 城墙耐久发展增值
        /// </summary>
        /// <param name="days">天数</param>
        /// <param name="fund">资金</param>
        /// <returns></returns>
        public void DevelopEndurance(int days, int fund)
        {
            double ret0 = Population * 0.000001;//人口加成，十万分之一
            double ret5 = fund * 0.01;//资金加成
            double ret6 = 0;//武将政治加成
            double ret7 = 0;//武将统率加成
            foreach (var officer in this.OwnedOfficers.Where(x => x.WorkType == WorkType.Endurance).ToList())
            {
                ret6 += officer.Politics * 0.05;
                ret7 += officer.Commander * 0.10;
                officer.UpdateDevelopEndurancePerformance(days);
            }
            double total = ret0 + ret5 + ret6 + ret7;
            int ret = (int)(total * days);//天数加成，取整
            this.Endurance += ret;
            if (this.CurrentBuildingLevel != null)
            {
                if (this.Endurance > CurrentBuildingLevel.EnduranceMax)
                    this.Endurance = CurrentBuildingLevel.EnduranceMax;
            }
            else
            {
                if (this.Endurance > this._fixEnduranceMax)
                    this.Endurance = this._fixEnduranceMax;
            }
           
            Logger.Info("耐久加成:" + ret);
        }
        /// <summary>
        /// 征兵值
        /// </summary>
        /// <param name="days">天数</param>
        /// <param name="fund">资金</param>
        /// <returns></returns>
        public void DevelopSoldier(int days, int fund)
        {
            double ret5 = fund * 1;//资金加成
            double ret6 = 0;//武将政治加成
            double ret7 = 0;//武将统率加成
            double ret8 = 0;//武将魅力加成
            double ret9 = 0;//武将声望加成
            foreach (var officer in this.OwnedOfficers.Where(x => x.WorkType == WorkType.RecruitSoldier).ToList())
            {
                ret6 += officer.Politics * 0.1;
                ret7 += officer.Commander * 0.1;
                ret8 += officer.Glamour * 0.1;
                ret9 += officer.Reputation * 0.01;
                officer.UpdateDevelopSoldierPerformance(days);
            }
            double total = ret5 + ret6 + ret7 + ret8 + ret9;
            int ret = (int)(total * days);//天数加成，取整
            if (ret > this.SoldierPopulation)
                ret = this.SoldierPopulation;
            this.SoldierCount += ret;
            this.SoldierPopulation -= ret;
            Logger.Info("征兵:" + ret);
        }
        /// <summary>
        /// 扩建加成
        /// </summary>
        public void DevelopExtendBuilding(int days, int fund)
        {
            if (this.CurrentBuildingLevel == null)
                return;
            double ret0 = Population * 0.000001;//人口加成，十万分之一
            double ret5 = fund * 0.01;//资金加成
            double ret6 = 0;//武将政治加成
            double ret7 = 0;//武将统率加成
            foreach (var officer in this.OwnedOfficers.Where(x => x.WorkType == WorkType.ExtendBuilding).ToList())
            {
                ret6 += officer.Politics * 0.05;
                ret7 += officer.Commander * 0.10;
                officer.UpdateDevelopExtendBuildingPerformance(days);
            }
            double total = ret0 + ret5 + ret6 + ret7;
            int ret = (int)(total * days);//天数加成，取整
            this.CurrentExtendBuilding += ret;
            BuildingLevel nextLevel = BuildingLevel.BuildingLevels[(short)(CurrentBuildingLevel.Id + 1)];
            if (this.CurrentExtendBuilding >= nextLevel.EnduranceMax)//扩建值达到下个城池等级耐久最大值，则扩建成功
            {
                this.CurrentBuildingLevel = nextLevel;
                this.Endurance = nextLevel.EnduranceMax;
                this.CurrentExtendBuilding = 0;
                this.IsExtendingBuilding = false;
                Logger.Info("扩建完成，等级:" + this.CurrentBuildingLevel.Id);
            }

            Logger.Info("扩建加成:" + ret);

        }
        /// <summary>
        /// 人口兵役变化
        /// </summary>
        public void UpdatePopulationChange(int days)
        {
            if (this.CurrentBuildingLevel == null)
                return;
            double ret0 = this.Population * 0.1 / 365;//人口新生人数，十分之一
            double ret1 = -ret0 / 2;//人口老龄化死亡人数，是出生人数二分之一
            double total = ret0 + ret1;
            int ret = (int)(total * days);//天数加成，取整
            int oldPopulation = this.Population;
            this.Population += ret;
            if (this.Population > this.CurrentBuildingLevel.PopulationMax)
            {
                this.Population = this.CurrentBuildingLevel.PopulationMax;
            }
            int actual = this.Population - oldPopulation;
            this.SoldierPopulation += actual / 2;//兵役人口增长为实际人口增长的1/2
            Logger.Info("人口加成:" + ret + ",兵役加成:" + (int)(actual / 2));

        }
        /// <summary>
        /// 资金税收
        /// </summary>
        public void GetFundTax(int days)
        {
            if (this.CurrentBuildingLevel == null)
                return;
            this.Fund += this.Commerce*days;

        }
        /// <summary>
        /// 发放月俸
        /// </summary>
        public void PayOffSalary()
        {
           if(this.LastPayDay.Month>=HistoryDate.CurrentDate.Month)//本月已经发放过月俸
               return;
            foreach (var officer in OwnedOfficers)
            {
                int salary = 2;//默认没有官职的武将月俸是2石。够吃8个人
                if (officer.OfficialPosition != null)
                    salary = officer.OfficialPosition.Salary;
                //月俸一半粮食一半钱
                int foodCount = (int)(salary/2);
                int fundCount = salary/2*500;
                if (this.Food >= foodCount)//粮食充足，使用粮食支付一半工资
                    this.Food -= foodCount;
                else
                {
                    if (this.Fund >= foodCount*500)//粮食不足，则自动使用钱换算后支付
                        this.Fund -= foodCount*500;
                    else
                        officer.LoyaltyIndex -= 2;//发不起工资，忠诚度降低
                }
                if (this.Fund >= fundCount)//钱充足，使用钱支付一半工资
                    this.Fund -= fundCount;
                else
                {
                    if (this.Food >=  (int)(fundCount / 500))//钱不足，则自动使用粮食换算后支付
                        this.Food -= (int)(fundCount / 500);
                    else
                        officer.LoyaltyIndex -= 2;//发不起工资，忠诚度降低
                }
            }

        }
        /// <summary>
        /// 粮食税收
        /// </summary>
        public void GetFoodTax()
        {
            if (this.CurrentBuildingLevel == null||this.LastHarvest.Year>=HistoryDate.CurrentDate.Year)
                return;
            if(HistoryDate.CurrentDate.Month!=5)  //冬小麦5月份收获
                return;
            this.Food += this.Agriculture;
            this.LastHarvest = HistoryDate.CurrentDate;

        }
        /// <summary>
        /// 计算到目标城池的路程(天数)
        /// </summary>
        /// <param name="building"></param>
        /// <returns></returns>
        public int ComputeDaysFromTargetBuilding(Building building)
        {
            int x = Math.Abs(this.Position.X - building.Position.X);
            int y = Math.Abs(this.Position.Y - building.Position.Y);
            int z=(int) (Math.Sqrt(x*x + y*y)/4);
            return z;
        }

        public void UpdateOfficerPosition()
        {
            
        }
    }
}
